/*******************************************************************************
    文件名称： 
	开发者：孙磊
	开发时间地点：2013.12.8 
	邮箱：zhongyuansunlei@163.com
	版本信息：
		
********************************************************************************/
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/epoll.h>
#include "wrapepoll.h"
#include "log.h"


#define EP_MAX_SIZE		64

void vevent_set(
	event* pevent, 
	int ifd, 
	void (*func)(int, int event, void* arg), 
	void* arg, 
	int ievent)
{
	pevent->m_ifd = ifd;
	pevent->m_func = func;
	pevent->m_parg = arg;
	
	if(EV_READ == ievent) {
		pevent->m_ievent = EPOLLIN ;
	} else {
		pevent->m_ievent = EPOLLOUT ;
	}
}

int ievent_create(int *pepfd) 
{
	*pepfd = epoll_create(EP_MAX_SIZE);
	if(*pepfd == -1) {
		Trace("epoll_create error , errno = %d\n", errno);	
		return -1;
	}
	
	return 0;
}

int ievent_add(int iepfd, event* pevent)
{
	int irtn = 0;
	
	struct epoll_event oepev;
	oepev.data.fd = pevent->m_ifd; 
	oepev.events =  pevent->m_ievent;
	oepev.data.ptr = pevent;
	
	irtn = epoll_ctl(iepfd, EPOLL_CTL_ADD, pevent->m_ifd, &oepev);
	if(irtn == -1) {
		Trace("epoll_ctl error , errno = %d\n", errno);	
		return irtn;
	}
	
	return irtn;
}

int ievent_del(int iepfd, event* pevent)
{
	int irtn = 0;
	
	struct epoll_event oepev;
	memset(&oepev, 0, sizeof(oepev));
	oepev.data.fd = pevent->m_ifd; 
	oepev.events =  pevent->m_ievent;
	oepev.data.ptr = pevent;
	
	irtn = epoll_ctl(iepfd, EPOLL_CTL_DEL, pevent->m_ifd, &oepev);
	if(irtn == -1) {
		Trace("epoll_ctl error , errno = %d\n", errno);	
		return irtn;
	}
	
	return irtn;
}

int ievent_loop(int iepfd, int itimeout)
{
	int inums, i;
	inums = i = 0;
	struct epoll_event oepoll_event[EP_MAX_SIZE];
	
	while(true) {
		inums = epoll_wait(iepfd, oepoll_event, EP_MAX_SIZE, itimeout);
		if(inums == 0) {
			Trace("5 secs passed away!\n"); fflush(stdin);
		}	else {
			//if((errno == EINTR) || (errno == EAGAIN ))
			if(errno == EINTR)
				continue;
			//Trace("[%s:%d]inums = %d, errno = %d\n", __FILE__, __LINE__, inums, errno);
		}
		for(i=0;i<inums;i++) {
			((event*)(oepoll_event[i].data.ptr))->m_func(
				((event*)(oepoll_event[i].data.ptr))->m_ifd,
				((event*)(oepoll_event[i].data.ptr))->m_ievent,
				((event*)(oepoll_event[i].data.ptr))->m_parg);
		}
	}
	
	return 0;
}

int iev_mem_alloc_cpy(node* p1, void* p2)
{
	event* pev = (event*)p2;
	p1->m_pvalue = (void*)malloc(sizeof(event));
	if(p1->m_pvalue == NULL) {
		Trace("malloc failed\n");
		return -1;
	}
	
	memcpy(p1->m_pvalue, pev, sizeof(event));
	
	return 0;
}

int iev_cmp(node*p1, void* p2)
{
	event *v1, *v2;
	
	v1 = (event*)p1->m_pvalue;
	v2 = (event*)p2;
	
	if(v1 == NULL) return 1;
	
	if(v1->m_ifd == v2->m_ifd) 
		return 0;
	else 
		return 1;
}

int iev_hash(void* p2)
{
	event* v= (event*)p2;
	
	return v->m_ifd;
}


void vev_free(void*p)
{
	event* v = (event*)p;
	free(v->m_parg);
	free(v);
}


/*
void print1(int ifd)
{
	char sbuffer[128];
	memset(sbuffer, 0, 128);
	
	if(read(ifd, sbuffer, 128)== -1) {
		Trace("read1 error!ifd = %d\n", ifd);
		exit(-1);
	}
	
	Trace("print1 read, string = %s ", sbuffer);
	
	return;
}

void print2(int ifd)
{
	char sbuffer[128];
	memset(sbuffer, 0, 128);
	
	if(read(ifd, sbuffer, 128)== -1) {
		Trace("read2 error!ifd = %d\n", ifd);
		exit(-1);
	}
	
	Trace("print2 read, string = %s ", sbuffer);
	
	return;
}



int main()
{
	int ifd[4], i, epfd;
	
	if(ievent_create(&epfd)) {
		Trace("ievent_create error!\n");
		return -1;
	} 
	
	if(pipe(ifd)) {
		Trace("pipe error\n");
		return -1;
	}
	
	if(pipe(ifd+2)) {
		Trace("pipe error\n");
		return -1;
	}
	
	struct event oevent[2];
	
	vevent_set(&oevent[0], ifd[0], print1, NULL, EPOLLIN|EPOLLET);
	ievent_add(epfd, &oevent[0]);
	
	
	vevent_set(&oevent[1], ifd[2], print2, NULL, EPOLLIN|EPOLLET);
	ievent_add(epfd, &oevent[1]);
	
	
	pid_t pid = fork();
	if(pid<0) {
		Trace("fork error");
		exit(-1);
	} else if(pid == 0) {
		int j = 0;
		char swbuffer[64];
		while(true) {
			
			memset(swbuffer, 0, 64);
			sprintf(swbuffer, "xxxx%5d", j++);
			if((j%2) == 0) {
				if(write(ifd[1], swbuffer, strlen(swbuffer)) == -1) {
					Trace("write error\n");
					exit(-1);
				}
				Trace("write ifd[1]%s\n", swbuffer);
			} else {
				if(write(ifd[3], swbuffer, strlen(swbuffer)) == -1) {
					Trace("write error\n");
					exit(-1);
				}
				
				Trace("write ifd[3] %s\n", swbuffer);
			}
			sleep(8);
			
		}
	} 
	
	ievent_loop(epfd, 5000);
	
	
	return 0;
}



int main()
{
	event oevent[2];
	int ifd[2], i, epfd;
	char sfile[64];
	
	if(ievent_create(&epfd)) {
		Trace("ievent_create error!\n");
		return -1;
	} 
	
	//for(i=0;i<2;i++) {
	//	memset(sfile, 0, 64);
	//	sprintf(sfile, "FILE_00%d", i);
	//	if(ifd[i]=open(sfile,O_RDWR|O_CREAT)== -1) {
	//		Trace("open file error, errno = %d\n", errno);
	//		return -1;
	//	}
	//	if(i==0) {
	//		vevent_set(&oevent[i], ifd[i], print1, NULL, EPOLLIN|EPOLLET);
	//	} else {
	//		vevent_set(&oevent[i], ifd[i], print2, NULL, EPOLLIN|EPOLLET);
	//	}
	//	
	//	ievent_add(epfd, &oevent[i]);
	//}
	//
	//
	//ievent_loop(epfd, 5000);
	
	

	
	if(pipe(ifd)) {
		Trace("pipe error\n");
		return -1;
	}
	
	pid_t pid = fork();
	if(pid<0) {
		Trace("fork error");
		exit(-1);
	} else if(pid == 0) {
		int j = 0;
		char swbuffer[64];
		while(true) {
			memset(swbuffer, 0, 64);
			sprintf(swbuffer, "%5d", j++);
			if(write(ifd[1], swbuffer, strlen(swbuffer)) == -1) {
				Trace("write error\n");
				exit(-1);
			}
			Trace("write %s\n", swbuffer);
			sleep(1);
			
		}
	} 
	
	epoll_event oepoll_event;
	epoll_event g_oepoll_event[64];
	
	
	oepoll_event.data.fd = ifd[0];  
	oepoll_event.events = EPOLLIN | EPOLLET;//读入,边缘触发方式  
	if(epoll_ctl(epfd, EPOLL_CTL_ADD, ifd[0],&oepoll_event)) {
		Trace("epoll_ctl error, errno = %d\n", errno);
		return -1;
	}
	
	int inum;
	char sbuffer[64];
	while(true) {
		inum = epoll_wait(epfd, g_oepoll_event, 64, 5000);
		if(inum == 0) {
			Trace("timeout happened\n");
		}
		
		for(i=0;i<inum;i++) {
			//Trace("i = %d\n", i);
			memset(sbuffer, 0, 64);
			if(read(ifd[0], sbuffer, 64)==-1) {
				Trace("read error\n");
				exit(-1);
			}
			
			Trace("read %s\n", sbuffer);
		}
	}
	
	
	return 0;
}

*/
